package com.jp.juc.taskFrame.domain.vo;


import com.jp.juc.taskFrame.context.CheckJobProcess;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 类说明：提交给框架执行的工作实体类,
 * 工作：表示本批次需要处理的同性质任务(Task)的一个集合
 */
public class JobInfo<R> {
    /*工作名，用以区分框架中唯一的工作*/
    private final String jobName;
    /*工作中任务的长度*/
    private final int jobLength;

    /*处理工作中任务的处理器*/
    private final TaskProcess<?, ?> taskProcess;
    /*任务的成功次数*/
    private AtomicInteger successCount;
    /*工作中任务目前已经处理的次数*/
    private AtomicInteger taskProcessCount;
    /*存放每个任务的处理结果，供查询用（双端队列 获取任务进度是从头取，完成的任务往尾插入）*/
    private LinkedBlockingDeque<TaskResult<R>> taskDetailQueues;
    /*保留的工作的结果信息供查询的时长*/
    private final long expireTime;

    private static CheckJobProcess checkJob = CheckJobProcess.getInstance();


    public JobInfo(String jobName, int jobLength, TaskProcess<?, ?> taskProcess, long expireTime) {
        this.jobName = jobName;
        this.jobLength = jobLength;
        this.taskProcess = taskProcess;
        this.expireTime = expireTime;
        successCount = new AtomicInteger(0);
        taskProcessCount = new AtomicInteger(0);
        taskDetailQueues = new LinkedBlockingDeque<>(jobLength);
    }

    public int getSuccessCount() {
        return successCount.get();
    }

    public int getTaskProcessCount() {
        return taskProcessCount.get();
    }

    //提供工作中失败的次数
    public int getFailCount() {
        return taskProcessCount.get() - successCount.get();
    }

    public int getJobLength() {
        return jobLength;
    }

    public TaskProcess<?, ?> getTaskProcess() {
        return taskProcess;
    }

    /*提供工作的整体进度信息*/
    public String getTotalProcess() {
        return "Success[" + successCount.get() + "]/Current[" + taskProcessCount.get() + "] Total[" + jobLength + "]";
    }

    public TotalProcess getTotalProcessObj() {
        return new TotalProcess(successCount.get(), taskProcessCount.get(), jobLength);
    }

    /*提供工作中每个任务的处理结果*/
    public List<TaskResult<R>> getTaskDetail() {
        List<TaskResult<R>> taskResultList = new LinkedList<>();

        TaskResult<R> taskResult;
        while ((taskResult = taskDetailQueues.pollFirst()) != null) {
            taskResultList.add(taskResult);
        }
        return taskResultList;
    }

    /*每个任务处理完成后，记录任务的处理结果，因为从业务应用的角度来说，
         对查询任务进度数据的一致性要不高
        我们保证最终一致性即可，无需对整个方法加锁*/
    public void addTaskResult(TaskResult<R> taskResult) {
        // 任务正常处理时
        if (TaskResultType.Success.equals(taskResult.getResultType())) {
            successCount.incrementAndGet();
        }

        taskProcessCount.incrementAndGet();
        taskDetailQueues.addLast(taskResult);
        // 任务全部完成
        if (taskProcessCount.get() == jobLength) {
            checkJob.putJob(jobName, expireTime);
        }
    }
}
